import { find } from "lodash";
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import cx from "classnames";
import Input from "antd/lib/input";
import Select from "antd/lib/select";
import { Dashboard } from "@/services/dashboard";
import notification from "@/services/notification";
import { DashboardTagsControl } from "@/components/tags-control/TagsControl";
import useSearchResults from "@/lib/hooks/useSearchResults";

const { Option } = Select;
function search(term) {
  if (term === null) {
    return Promise.resolve(null);
  }

  if (!term) {
    return Dashboard.publish().then(results => results.filter(item => !item.is_draft)); // filter out draft
  }

  // search by dashboard
  return Dashboard.query({ q: term }).then(({ results }) => results);
}

export default function DashboardSelector(props) {
  const [searchTerm, setSearchTerm] = useState("");
  const [selectedDashboard, setSelectedDashboard] = useState();
  const [doSearch, searchResults, searching] = useSearchResults(search, { initialResults: [] });

  const placeholder = "按名称搜索查询…";
  const clearIcon = <i className="fa fa-times hide-in-percy" onClick={() => selectDashboard(null)} />;
  const spinIcon = <i className={cx("fa fa-spinner fa-pulse hide-in-percy", { hidden: !searching })} />;

  useEffect(() => {
    doSearch(searchTerm);
  }, [doSearch, searchTerm]);

  // set selected from prop
  useEffect(() => {
    if (props.selectedDashboard) {
      setSelectedDashboard(props.selectedDashboard);
    }
  }, [props.selectedDashboard]);

  function selectDashboard(dashboardId) {
    let dashboard = null;
    if (dashboardId) {
      dashboard = find(searchResults, { id: dashboardId });
      if (!dashboard) {
        // shouldn't happen
        notification.error("意外错误...", "不能选取报表");
      }
    }

    setSearchTerm(dashboard ? null : ""); // empty string triggers recent fetch
    setSelectedDashboard(dashboard);
    props.onChange(dashboard);
  }

  function clearDashboard() {
    setSelectedDashboard(null);
    props.onChange(null);
  }

  function renderResults() {
    if (!searchResults.length) {
      return <div className="text-muted">没有搜索到匹配的记录。</div>;
    }

    return (
      <div className="list-group">
        {searchResults.map(q => (
          <a
            className={cx("dashboard-selector-result", "list-group-item", { inactive: q.is_draft })}
            key={q.id}
            onClick={() => selectDashboard(q.id)}
            data-test={`DashboardId${q.id}`}>
            {q.name} <DashboardTagsControl isDraft={q.is_draft} tags={q.tags} className="inline-tags-control" />
          </a>
        ))}
      </div>
    );
  }

  if (props.disabled) {
    return <Input value={selectedDashboard && selectedDashboard.name} placeholder={placeholder} disabled />;
  }

  if (props.type === "select") {
    const suffixIcon = selectedDashboard ? clearIcon : null;
    const value = selectedDashboard ? selectedDashboard.name : searchTerm;

    return (
      <Select
        showSearch
        allowClear
        dropdownMatchSelectWidth={false}
        placeholder={placeholder}
        value={value || undefined} // undefined for the placeholder to show
        onSearch={setSearchTerm}
        onClear={clearDashboard}
        onChange={selectDashboard}
        suffixIcon={searching ? spinIcon : suffixIcon}
        notFoundContent={null}
        filterOption={false}
        defaultActiveFirstOption={false}
        className={props.className}
        data-test="DashboardSelector">
        {searchResults &&
          searchResults.map(q => {
            const disabled = q.is_draft;
            return (
              <Option
                value={q.id}
                key={q.id}
                disabled={disabled}
                className="dashboard-selector-result"
                data-test={`DashboardId${q.id}`}>
                {q.name}{" "}
                <DashboardTagsControl
                  isDraft={q.is_draft}
                  tags={q.tags}
                  className={cx("inline-tags-control", { disabled })}
                />
              </Option>
            );
          })}
      </Select>
    );
  }

  return (
    <span data-test="DashboardSelector">
      {selectedDashboard ? (
        <Input value={selectedDashboard.name} suffix={clearIcon} readOnly />
      ) : (
        <Input
          placeholder={placeholder}
          value={searchTerm}
          onChange={e => setSearchTerm(e.target.value)}
          suffix={spinIcon}
        />
      )}
      {!selectedDashboard && (
        <div className="scrollbox" style={{ maxHeight: "50vh", marginTop: 15 }}>
          {searchResults && renderResults()}
        </div>
      )}
    </span>
  );
}

DashboardSelector.propTypes = {
  onChange: PropTypes.func.isRequired,
  selectedDashboard: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  type: PropTypes.oneOf(["select", "default"]),
  className: PropTypes.string,
  disabled: PropTypes.bool,
};

DashboardSelector.defaultProps = {
  selectedDashboard: null,
  type: "default",
  className: null,
  disabled: false,
};
